/*
 * Copyright 2020-2030 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.extraty.question1691;

import lombok.Generated;

import java.util.Arrays;

/**
 * @author Created by Neil Wang
 * @version 1.0.0
 * @date 2021/9/6 1:22 下午
 */
public class Solution1 {
    public int maxHeight(int[][] cuboids) {
        int[][] newCuboids = new int[6 * cuboids.length][3];
        Integer[] index = new Integer[6 * cuboids.length];
        generateAllConditionsCuboids(cuboids, cuboids.length, 6 * cuboids.length, newCuboids, index);
        return getMaxHeight(6 * cuboids.length, newCuboids, index);
    }

    private int getMaxHeight(int allConditionsSize, int[][] newCuboids, Integer[] index) {
        int max = 0;
        int[] dp = new int[allConditionsSize];
        for (int i = 0; i < allConditionsSize; i++) {
            dp[i] = newCuboids[index[i]][2];
            for (int j = 0; j < i; j++) {
                if (ignoreAdd(newCuboids, index[i], index[j])) continue;
                dp[i] = Math.max(dp[i], dp[j] + newCuboids[index[i]][2]);
            }
            max = Math.max(max, dp[i]);
        }
        return max;
    }

    @Generated
    private boolean ignoreAdd(int[][] newCuboids, Integer index1, Integer index2) {
        return index1 / 6 == index2 / 6 || newCuboids[index2][0] > newCuboids[index1][0]
                || newCuboids[index2][1] > newCuboids[index1][1] || newCuboids[index2][2] > newCuboids[index1][2];
    }

    private void generateAllConditionsCuboids(int[][] cuboids, int cuboidsLength, int allConditionsSize, int[][] newCuboids, Integer[] index) {
        for (int i = 0; i < cuboidsLength; i++) {
            newCuboids[6 * i] = cuboids[i];
            newCuboids[6 * i + 1] = new int[]{cuboids[i][1], cuboids[i][0], cuboids[i][2]};
            newCuboids[6 * i + 2] = new int[]{cuboids[i][1], cuboids[i][2], cuboids[i][0]};
            newCuboids[6 * i + 3] = new int[]{cuboids[i][2], cuboids[i][1], cuboids[i][0]};
            newCuboids[6 * i + 4] = new int[]{cuboids[i][0], cuboids[i][2], cuboids[i][1]};
            newCuboids[6 * i + 5] = new int[]{cuboids[i][2], cuboids[i][0], cuboids[i][1]};
        }
        for (int i = 0; i < allConditionsSize; i++) index[i] = i;
        Arrays.sort(index, (a, b) -> sortRule(newCuboids, a, b));
    }

    private int sortRule(int[][] newCuboids, Integer a, Integer b) {
        if (newCuboids[a][0] == newCuboids[b][0] && newCuboids[a][1] == newCuboids[b][1])
            return newCuboids[a][2] - newCuboids[b][2];
        if (newCuboids[a][0] == newCuboids[b][0]) return newCuboids[a][1] - newCuboids[b][1];
        return newCuboids[a][0] - newCuboids[b][0];
    }
}
